home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Univers Interactif 3
/
INTERACTIF.BIN
/
mac
/
Planete.net
/
Internet Confirmés_Vrac
/
NetAgent.sea
/
src
/
nntp_tcp.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-06-15
|
10KB
|
377 lines
/*
This is an unsupported product. It was developed as part of a study at Ostfold
Regional College, Norway in the spring of 1992.
You use this software at your own risk. Neither the authors nor the Ostfold
Regional College nor any other person or organization except yourself is
responsible for any damage or loss of data derived from the use of this
software. You may distribute this software freely as long as it is in its
original form and all of its files are included. If you make any changes to any
part of this software or the files distributed with it, please state so and do
NOT distribute it under its original name.
*/
#include <stdio.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netdb.h>
#include <sys/types.h>
#include <sys/time.h>
#define BACKLOG 10
#define MAXHOSTNAME 32
#define RETURN 13
#define LINEFEED 10
char *myname;
char buf[BUFSIZ+1];
struct sockaddr_in sa;
struct hostent *hp;
struct servent *sp;
/*
-----------------------------------------------------------------------------
Function name: tcp_connect()
-----------------------------------------------------------------------------
Parameters: char *host Name of the host to connect.
char *prot The protocol to use.
Return value: returns a socket.
Called by: main() (agentc)
Calls: none
Description: Sets up a connection to the host using the protocol
specified by prot.
-----------------------------------------------------------------------------
*/
int tcp_connect(host, prot)
char *host;
char *prot;
{
int s;
int len;
if((hp = gethostbyname(host)) == NULL) {
fprintf(stderr, "%s: %s: no such host?\n", myname, host);
exit(1);
}
bcopy((char*)hp->h_addr, (char*)&sa.sin_addr, hp->h_length);
sa.sin_family = hp->h_addrtype;
if((sp = getservbyname(prot, "tcp")) == NULL) {
fprintf(stderr, "%s: No %s service on %s\n", myname, prot, host);
exit(1);
}
sa.sin_port = sp->s_port;
if((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {
perror("socket");
exit(1);
}
if(connect(s, &sa, sizeof(sa)) < 0 ) {
perror("connect");
exit(1);
}
return(s);
}
/*
-----------------------------------------------------------------------------
Function name: tcp_connect_listen()
-----------------------------------------------------------------------------
Parameters: int port The port on which to listen.
Return value: Returns a socket.
Called by: main() (agentd)
Calls: none
Description: Reserves a port on wich to listen on.
-----------------------------------------------------------------------------
*/
int tcp_connect_listen(port)
int port;
{
int s;
int len;
char localhost[MAXHOSTNAME+1];
gethostname(localhost, MAXHOSTNAME);
if((hp = gethostbyname(localhost)) == NULL) {
fprintf(stderr, "%s: %s: no such host?\n", myname);
exit(1);
}
sa.sin_port = port;
bcopy((char*)hp->h_addr, (char*)&sa.sin_addr, hp->h_length);
sa.sin_family = hp->h_addrtype;
if((s = socket(hp->h_addrtype, SOCK_STREAM, 0)) < 0) {
perror("socket");
exit(1);
}
if(bind(s, &sa, sizeof(sa)) < 0 ) {
perror("bind");
exit(1);
}
listen(s, BACKLOG);
return(s);
}
/*
-----------------------------------------------------------------------------
Function name: tcp_send()
-----------------------------------------------------------------------------
Parameters: int s The socket on which the data is send.
char *data Pointer to a buffer which contains the data
to be send.
Return value: none
Called by: do_server(), help(), reg_user(), send_user_error(),
nytt(), nytt_ord(), new_words(), new_news(),
hent_nye_innlegg(), get_list(), do_innlegg()
Calls: none
Description: Sends data to the given socket.
-----------------------------------------------------------------------------
*/
void tcp_send(s, data)
int s;
char *data;
{
if(write(s,data , strlen(data)) != strlen(data)) {
fprintf(stderr, "%s: write error\n", myname);
exit(1);
}
}
/*
-----------------------------------------------------------------------------
Function name: tcp_answer()
-----------------------------------------------------------------------------
Parameters: int s The socket on wich to recieve data.
int f File descriptor on which to write the data
recieved.
Return value: none
Called by: none
Calls: none
Description: Reads data from a socket and writes them to a file.
-----------------------------------------------------------------------------
*/
void tcp_answer(s, f)
int s;
int f;
{
int len;
int more;
int width;
int read_ready;
fd_set read_socket;
struct timeval timeout;
timeout.tv_sec = 4;
timeout.tv_usec = 5;
width = (int) ulimit(4, 0);
FD_ZERO(&read_socket);
FD_SET(s, &read_socket);
while((read_ready = select(width, &read_socket, NULL, NULL, &timeout)) > 0) {
len = read(s, buf, BUFSIZ);
if(len <= 0) return;
write(f, buf, len);
}
if(read_ready < 0) {
perror("select");
exit(1);
}
}
/*
-----------------------------------------------------------------------------
Function name: get_msg()
-----------------------------------------------------------------------------
Parameters: int s Socket on which to recive data.
char okchar A character indicating if everything went
ok. This is matched against the first
character recieved.
char uptochar A character indicating when to stop reading
from s.
char *buffer The buffer to put the characters read.
int timeout The time in seconds after a timeout will
occur if no data is recieved at s.
Return value: -1 timeout occured
0 the okchar didn't match the first character read.
1 success
Called by: main() (agentc), do_innlegg()
Calls: none
Description: Recives data on s until uptochar is read.
-----------------------------------------------------------------------------
*/
int get_msg( s, okchar, uptochar, buffer, time_out)
int s;
char okchar;
char uptochar;
char *buffer;
int time_out;
{
int len;
int width;
int read_ready;
fd_set read_socket;
struct timeval timeout;
char ch_read[3];
int teller = 0;
timeout.tv_sec = time_out;
timeout.tv_usec = 0;
width = (int) ulimit(4, 0);
FD_ZERO(&read_socket);
FD_SET(s, &read_socket);
while((read_ready = select(width, &read_socket, NULL, NULL, &timeout)) >
0) {
len = read(s, ch_read, 1);
ch_read[1] = '\0';
if(len <= 0)
return(-2);
if(ch_read[0] == uptochar) {
buffer[teller] = '\0';
if(buffer[0] == okchar)
return(1);
else return(0);
}
buffer[teller++] = ch_read[0];
}
if(read_ready < 0) {
perror("select");
exit(1);
}
else if(read_ready == 0 )
return(-1);
}
/*
-----------------------------------------------------------------------------
Function name: recv_upto()
-----------------------------------------------------------------------------
Parameters: int s Socket on wich to recieve data.
char uptochar The stop character. This function reads data
until this character is read.
char *buffer The buffer in wich to put the data read.
int timeout The time to wait for response on the socket.
Return value: -2 on error
-1 on timeout
1 on success
Called by: do_server(), get_list()
Calls: none
Description: This function reads data from the socket s until it reads
uptochar. The characters read is put into buffer.
-----------------------------------------------------------------------------
*/
int recv_upto( s, uptochar, buffer, time_out)
int s;
char uptochar;
char *buffer;
int time_out;
{
int len;
int width;
int read_ready;
fd_set read_socket;
struct timeval timeout;
char ch_read[3];
int teller = 0;
timeout.tv_sec = time_out;
timeout.tv_usec = 0;
width = (int) ulimit(4, 0);
FD_ZERO(&read_socket);
FD_SET(s, &read_socket);
while((read_ready = select(width, &read_socket, NULL, NULL, &timeout)) >
0) {
len = read(s, ch_read, 1);
ch_read[1] = '\0';
if(len <= 0)
return(-2);
if(ch_read[0] == uptochar) {
buffer[teller] = '\0';
return(1);
}
buffer[teller++] = ch_read[0];
}
if(read_ready < 0) {
perror("select");
exit(1);
}
else if(read_ready == 0 )
return(-1);
}
/*
-----------------------------------------------------------------------------
Function name: get_list()
-----------------------------------------------------------------------------
Parameters: int s The socket on which to recive.
int fp The file on which to write the retrived data.
int timeout How long, in seconds, the function should
wait if it doesn't recieve any data.
Return value: 1 on success
Called by: hent_nye_innlegg(), new_words()
Calls: recv_upto(), tcp_send()
Description: The function recives data until it reads a '.' character.
The data is written to a file.
-----------------------------------------------------------------------------
*/
int get_list(s, fp, time_out)
int s;
int fp;
int time_out;
{
char linje[BUFSIZ+1];
char skriv_ut[BUFSIZ+1];
char *buf;
int ferdig = 0;
linje[0] = '\0';
while(!ferdig) {
if(recv_upto(s,RETURN, linje, time_out) <= 0) {
tcp_send(s, "505 error or timeout - closing\n");
close(s);
exit(1);
}
buf = linje;
if(*buf == LINEFEED)
buf++;
if((strlen(linje)==2) && (linje[1] == '.'))
ferdig = 1;
else {
sprintf(skriv_ut, "%s\n", buf);
write(fp, skriv_ut, strlen(skriv_ut));
}
}
return(1);
}